<template>
  <el-dialog
    :title="title"
    :visible="dialogVisible"
    width="40%"
    @close="handleClose()"
    @open="openDialog()"
    @click.native="isShowTree = false"
  >
    <!-- 表单组件  el-form   label-width设置label的宽度   -->
    <!-- 匿名插槽 -->
    <el-form ref="addForm" :model="form" :rules="rules" label-width="120px">
      <el-form-item label="姓名" prop="username">
        <el-input
          v-model="form.username"
          style="width: 90%"
          placeholder="请输入姓名"
        />
      </el-form-item>
      <el-form-item label="手机" prop="mobile">
        <el-input
          v-model="form.mobile"
          style="width: 90%"
          placeholder="请输入手机号"
        />
      </el-form-item>
      <el-form-item label="入职时间" prop="timeOfEntry">
        <el-date-picker
          v-model="form.timeOfEntry"
          style="width: 90%"
          placeholder="请选择入职时间"
        />
      </el-form-item>
      <el-form-item label="聘用形式" prop="formOfEmployment">
        <el-select
          v-model="form.formOfEmployment"
          style="width: 90%"
          placeholder="请选择"
        >
          <!-- el-option组件中的属性解析：key为标识符和v-for中的key一样的作用。label是显示到页面的数据。value是返回接口的数据。 -->
          <el-option
            v-for="item in hireType"
            :key="item.id"
            :label="item.value"
            :value="item.id"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="工号" prop="workNumber">
        <el-input
          v-model="form.workNumber"
          style="width: 90%"
          placeholder="请输入工号"
        />
      </el-form-item>
      <el-form-item label="部门" prop="departmentName">
        <el-input
          :value="form.departmentName"
          style="width: 90%"
          placeholder="请选择部门"
          @click.native.stop="openTreeFn()"
        />
        <div v-if="isShowTree" class="tree-box">
          <el-tree
            v-loading="loading"
            :data="options"
            :props="defaultProps"
            @node-click="ondeClick"
          />
        </div>
      </el-form-item>
      <el-form-item label="转正时间" prop="correctionTime">
        <el-date-picker
          v-model="form.correctionTime"
          style="width: 90%"
          placeholder="请选择转正时间"
        />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleClose()">取 消</el-button>
        <el-button type="primary" @click="addDepartList()"> 确 定 </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script>
import { getDepartMentList } from '@/api/department'
import { recursionDepartsFn } from '@/utils'
import constants from '@/constant/employees'
import { addUserApi } from '@/api/employees'
import moment from 'moment'
export default {
  props: {
    // eslint-disable-next-line vue/require-prop-types
    dialogVisible: {
      typeof: Boolean,
      default: false
    },
    title: {
      type: String,
      required: true
    }
  },
  data() {
    // 工号不能重复
    // const checkWorkNumberRepeat = (rule, value, callback) => {
    //   let arr = []
    //   // 现在我们进行验证，如果form有id，那么现在就是编辑状态。
    //   if (this.form.id) {
    //     // 当然，在编辑状态下，我们可以选择是否对部门名称进行修改。
    //     // 如果我们不对部门名称进行修改，那么直接放行
    //     if (this.pdata.name === value) {
    //       callback()
    //       return
    //     } else {
    //       // 如果我们修改了部门名称，那么就要让它和它的兄弟部门进行比较，不能让它和它兄弟部门的名称一样
    //       // 首先将和它是同一个父亲的兄弟们都找到
    //       arr = this.oldDepartList.filter((item) => {
    //         return item.pid === this.pdata.pid
    //       })
    //     }
    //   } else {
    //     // 这是新增部门的状态
    //     arr = this.oldDepartList.filter((item) => {
    //       return item.pid === this.pdata.id
    //     })
    //   }
    //   // 然后让它和这些兄弟们进行对比
    //   const flag = arr.some((item) => item.name === value)
    //   flag ? callback(new Error('已经出现了同名的部门！')) : callback()
    // }
    return {
      form: {
        username: '', // 用户名
        mobile: '', // 手机号
        formOfEmployment: '', // 聘用形式
        workNumber: '', // 工号
        departmentName: '', // 部门
        timeOfEntry: '', // 入职时间
        correctionTime: '' // 转正时间
      },
      // 定义校验规则
      rules: {
        username: [
          {
            required: true,
            message: '用户姓名不能为空',
            trigger: ['blur', 'change']
          },
          {
            min: 1,
            max: 4,
            message: '用户姓名为1-4位',
            trigger: ['blur', 'change']
          }
        ],
        mobile: [
          {
            required: true,
            message: '手机号不能为空',
            trigger: ['blur', 'change']
          },
          {
            // 正则校验--pattern
            pattern: /^1[3-9]\d{9}$/,
            message: '手机号格式不正确',
            trigger: ['blur', 'change']
          }
        ],
        formOfEmployment: [
          {
            required: true,
            message: '聘用形式不能为空',
            trigger: ['blur', 'change']
          }
        ],
        workNumber: [
          {
            required: true,
            message: '工号不能为空',
            trigger: ['blur', 'change']
          }
          //   {
          //     validator: checkWorkNumberRepeat,
          //     trigger: 'blur'
          //   }
        ],
        departmentName: [
          {
            required: true,
            message: '部门不能为空',
            trigger: ['blur', 'change']
          }
        ],
        timeOfEntry: [
          {
            required: true,
            message: '请选择入职时间',
            trigger: ['blur', 'change']
          }
        ],
        correctionTime: [
          {
            required: true,
            message: '请选择转正时间',
            trigger: ['blur', 'change']
          }
        ]
      },
      //   处理完成后的部门负责人选项列表
      options: [],
      //  映射关系
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      //   控制tree的显示与隐藏
      isShowTree: false,
      loading: false, // 是否加载中
      // 聘用形式的遍历数组
      hireType: constants.hireType
    }
  },
  created() {},
  methods: {
    // 关闭弹层
    handleClose() {
      // 下面两行代码都可以关闭弹层
      //  1.this.$emit('closeDialogFn')
      //  2.this.$emit('update:dialogVisible', false)
      //  但是想要使用第二种办法是由先决条件的；因为我们是从父组件传过来的，是控制弹层的显隐的；我们点击取消就要给这个传过来的值赋个false，但是不能直接修改prop接收的值，那就要使用子传父值得方法了；这就有了以上两个方法得出现。第二种方法需要在父组件传给子组件值的时候添加个async的修饰符，然后按照下面 this.$emit('update:dialogVisible', "要传的值")的固定格式书写就可以子组件向父组件传值了
      // 重置原来的数据[这端重置数据的代码是要根据每个功能的情况而改变的。]
      this.form = {
        username: '',
        mobile: '',
        formOfEmployment: '',
        workNumber: '',
        departmentName: '',
        timeOfEntry: '',
        correctionTime: ''
      }
      this.$emit('update:dialogVisible', false)
      this.$refs.addForm.resetFields()
    },
    // 打开弹层自动触发的方法：调用获取部门列表负责人，并获取
    openDialog() {},
    // 新增员工和编辑员工共用
    addDepartList() {
      // 点击了{确认键}，首先要对表单进行验证，不能有空的,如果为空不让通过
      // 然后将新增的数据添加到数据库
      // 最后关闭弹出框，并且清空表单数据
      this.$refs.addForm.validate(async (valid) => {
        // 先对表单进行验证，只有验证通过了我们才能让其发起接口请求
        if (!valid) {
          // 校验不通过
          return
        } else {
          // 校验通过
          // 再来个if判断，因为添加部门和编辑部门用的是同一个方法
          if (this.form.id) {
            // 如果form这个对象有id，那就证明是编辑部门
            // await editDepartMentApi(this.form)
            this.$message.success('编辑部门成功！')
          } else {
            // 新增部门
            const data = this.form
            data.timeOfEntry = moment(data.timeOfEntry).format('YYYY-MM-DD')
            data.correctionTime = moment(data.correctionTime).format(
              'YYYY-MM-DD'
            )
            await addUserApi(data)
            this.$message.success('新增部门成功！')
          }
          // 关闭弹层
          this.handleClose()
          // 重新渲染组织架构
          this.$emit('getDepartList')
          // 子传父，或者子组件调用父组件的方法整理：
          // 新：this.$parent.父组件的方法。但是这个方法别乱用，因为如果你遇到了你的父组件是当做插槽在别的组件中使用呢？那么，这个时候的$parent指向的就不是我们想要的父组件了，而是我们父组件的父组件了。因为插槽的本质就是将我们的插槽里面的DOM插入插槽的父组件里面，相当于是一体了没有父子之分。
          // this.$emit('父组件的方法')
          //
        }
      })
    },
    // 获取部门列表
    async getDepartMent() {
      this.loading = true
      const res = await getDepartMentList()
      const deptsList = await recursionDepartsFn(res.data.depts, '')
      this.options = deptsList
      this.loading = false
    },
    // 点击部门input的操作
    openTreeFn() {
      // 我们想要一个点击了，本来是隐藏的现在因为点击了那就变成了显示，再点击那就又变成了隐藏。
      // 但是我们还要有一个点击空白的地方也要让弹层隐藏，那就要给整个大的table添加一个点击事件，然后利用事件冒泡的思想，让弹层关闭，当我们点击部门这个组件的时候，我们阻止事件冒泡，不让他触发table的点击事件，也就是不让弹层关闭，但是要是点击了别的地方，那就利用事件冒泡触发table的点击事件，让弹层关闭
      this.isShowTree = !this.isShowTree
      if (!this.isShowTree) return
      //   每次点击部门，我们都要请求一次最新的部门列表，因为我们需要最新的数据
      this.getDepartMent()
    },
    // 点击叶子节点的回调函数
    // 共三个参数，依次为：传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身。
    ondeClick(nodeData) {
      //   console.log(nodeData)
      //   我们需要的是叶子节点，所以要进行判断一下，我们点击的节点是不是叶子节点
      if (nodeData.children && nodeData.children.length > 0) return
      this.form.departmentName = nodeData.name
      //   选择完了，那就关闭弹层
      this.isShowTree = false
    }
  }
}
</script>

<style lang="scss" scoped>
.tree-box {
  position: absolute;
  width: 90%;
  min-height: 50px;
  left: 0;
  top: 45px;
  z-index: 100;
  border: 1px solid #ccc;
  border-radius: 4px;
  padding-right: 5px;
  overflow: hidden;
  background-color: #fff;
  max-height: 200px;
  overflow: auto;
  ::v-deep {
    .el-tree-node__content {
      height: auto;
    }
  }
}
</style>
